home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 4
/
Apprentice-Release4.iso
/
Source Code
/
C
/
Frameworks
/
Grant's CGI Framework 1.0b12
/
Util
/
ProcessUtil.c
< prev
next >
Wrap
Text File
|
1995-12-09
|
5KB
|
213 lines
/*****
*
* ProcessUtil.c
*
* This is a support file for "Grant's CGI Framework".
* Please see the license agreement that accompanies the distribution package
* for licensing details.
*
* Copyright ©1995 by Grant Neufeld
* grant@acm.com
* http://arpp1.carleton.ca/grant/
*
*****/
#include "MyConfiguration.h"
#include <Threads.h>
#include "compiler_stuff.h"
#include "globals.h"
#include "DebugUtil.h"
#include "ProcessUtil.h"
/*** LOCAL PROTOTYPES ***/
pascal void myThreadTermination ( ThreadID, void * );
/*** FUNCTIONS ***/
/* Determine if the current application is active (is in front of all others) */
Boolean
ProcessCurrentIsFront ( void )
{
#if kCompileWithForeground
Boolean isFront;
ProcessSerialNumber myPSN;
OSErr theErr;
/* get my process serial number. IM:Processes 2-21 */
theErr = GetCurrentProcess ( &myPSN );
if ( theErr != noErr )
{
/* might want to do something else here to handle the error */
return false;
}
isFront = ProcessIsFront ( &myPSN );
return isFront;
#else /* if not kCompileWithForeground */
return false;
#endif /* kCompileWithForeground */
} /* ProcessCurrentIsFront */
/* Determine if the specified application is active (is in front of all others) */
Boolean
ProcessIsFront ( ProcessSerialNumber *thePSN )
{
OSErr theErr;
ProcessSerialNumber frontPSN;
my_assert ( thePSN != nil, "\pProcessIsFront: thePSN ptr is nil" );
theErr = GetFrontProcess ( &frontPSN );
if ( theErr != noErr )
{
/* might want to do something else here to handle the error */
return false;
}
return ( (frontPSN.lowLongOfPSN == thePSN->lowLongOfPSN) &&
(frontPSN.highLongOfPSN == thePSN->highLongOfPSN) );
} /* ProcessIsFront */
/* Fill out an already allocated FSSpec with the current process' location.
Thanks to Gregory S. Combs for providing most of this function. */
OSErr
ProcessGetMyFSSpec ( FSSpec *procFileSpec )
{
OSErr theErr;
ProcessSerialNumber curPSN;
ProcessInfoRec procInfo;
Str255 appName;
my_assert ( procFileSpec != nil, "\pProcessGetMyFSSpec: procFileSpec ptr is nil" );
theErr = GetCurrentProcess ( &curPSN );
if ( theErr == noErr )
{
procInfo.processInfoLength = sizeof ( ProcessInfoRec );
procInfo.processName = appName;
procInfo.processAppSpec = procFileSpec;
theErr = GetProcessInformation ( &curPSN, &procInfo );
}
return theErr;
} /* ProcessGetMyFSSpec */
/** THREAD FUNCTIONS **/
#pragma mark -
/* Allocate a new thread from the existing pool of threads.
If there are no threads available, yield to other threads until one finishes. */
OSErr
MyNewThreadFromPool (
ThreadEntryProcPtr threadEntry,
void * threadParam,
void ** threadResult,
ThreadID * threadMade )
{
OSErr theErr;
short threadsFree;
#if kCompileWithThreadsOptional
my_assert ( gHasThreadMgr, "\pMyNewThreadFromPool: Thread Manager not available" );
#endif
theErr = GetFreeThreadCount ( kCooperativeThread, &threadsFree );
/* while there is no error, and there are no threads free, */
while ( (theErr == noErr) && (threadsFree <= nil) )
{
/* give other threads a chance to complete */
YieldToAnyThread ();
/* check if any other threads did complete */
theErr = GetFreeThreadCount ( kCooperativeThread, &threadsFree );
}
if ( theErr == noErr )
{
/* install the new thread using a premade thread */
theErr = NewThread ( kCooperativeThread, threadEntry, threadParam, nil,
kFPUNotNeeded + kUsePremadeThread, threadResult, threadMade );
}
if ( theErr == noErr )
{
/* set the termination function for the thread */
SetThreadTerminator ( *threadMade, myThreadTermination, nil );
/* increment the total number of sub-threads */
++gThreadTotal;
}
return theErr;
} /* MyNewThreadFromPool */
/* */
pascal void
myThreadTermination ( ThreadID threadTerminated, void *terminationProcParam )
{
#if kCompileWithThreadsOptional
my_assert ( gHasThreadMgr, "\pmyThreadTermination: Thread Manager not available" );
#endif
/* Lower the count of sub-threads */
--gThreadTotal;
} /* myThreadTermination */
/* Give all sub-threads a chance to finish */
void
ThreadFinishAllSubThreads ( void )
{
ThreadID currentThread;
#if kCompileWithThreadsOptional
my_assert ( gHasThreadMgr, "\pThreadFinishAllSubThreads: Thread Manager not available" );
#endif
GetCurrentThread ( ¤tThread );
if ( currentThread != gThreadMain )
{
/* lower the count of sub-threads to prevent this sub-thread from
preventing the exit of the while loop below */
--gThreadTotal;
}
while ( gThreadTotal > nil )
{
/* while there remain other threads (not including the current and main),
let them finish before quitting */
YieldToAnyThread ();
}
if ( currentThread != gThreadMain )
{
/* increase the count of sub-threads */
++gThreadTotal;
}
} /* ThreadFinishAllSubThreads */
/***** EOF *****/